package cn.edu.sdjzu.xg.bysj.controller.basic;


import cn.edu.sdjzu.xg.bysj.domain.Student;
import cn.edu.sdjzu.xg.bysj.service.StudentService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import util.Condition;
import util.ControllerHelper;
import util.JSONUtil;
import util.Pagination;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 将所有方法组织在一个Controller(Servlet)中
 *
 * @author 1033299034@qq.com
 */
@Slf4j
@WebServlet("/basic/student.ctl")
public class StudentController extends HttpServlet {
    //请使用以下JSON测试增加功能(id为空)
    //{
    //    "name":"XXX",
    //    "no":"XX",
    //    "remarks":"",
    //    "studentClass":{
    //        "id":"X",
    //        "description":"XX",
    //        "no":"XX",
    //        "remarks":"",
    //        "department":{
    //            "id":"X",
    //            "description":"XX",
    //            "no":"XX",
    //            "remarks":"",
    //            "school":{
    //                "id":"X",
    //                "description":"XX",
    //                "no":"XX",
    //                "remarks":""
    //            }
    //        }
    //    }
    //}
    /**
     * POST, http://localhost:8080/student.ctl, 增加学生
     * 增加一个学生对象：将来自前端请求的JSON对象，增加到数据库表中
     * @author 1033299034@qq.com
     * @param request  请求对象
     * @param response 响应对象
     * @throws IOException
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        //设置请求字符编码为UTF-8
        request.setCharacterEncoding("UTF-8");
        //根据request对象，获得代表参数的JSON字串
        String student_json = JSONUtil.getJSON(request);

        //将JSON字串解析为Student对象
        Student studentToAdd = JSON.parseObject(student_json, Student.class);

        //设置响应字符编码为UTF-8
        response.setContentType("application/json;charset=UTF-8");
        //创建JSON对象message，以便往前端响应信息
        JSONObject message = new JSONObject();
        //在数据库表中增加Student对象
        try {
            StudentService.getInstance().add(studentToAdd);
            message.put("message", "增加成功");
        } catch (SQLException e) {
            message.put("message", "数据库操作异常");
            //打印异常栈，方便调试
            log.error(e.getMessage(),e);
        } catch (Exception e) {
            message.put("message", "网络异常");
            //打印异常栈，方便调试
            log.error(e.getMessage(),e);
        }
        //响应message到前端
        response.getWriter().println(message);
    }

    //请使用以下JSON测试删除功能
    //{"id":"XX"}
    /**
     * DELETE, http://localhost:8080/student.ctl, 删除学生
     * 删除一个学生对象：将来自前端请求的JSON对象
     * @author 1033299034@qq.com
     * @param request  请求对象
     * @param response 响应对象
     * @throws IOException
     */
    @Override
    protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //将request参数转换为JSON字串
        String request_json_str = JSONUtil.getJSON(request);
        //将请求body解析为要删除的Student的id对应的JSONObject对象(可能是{"id":1})
        JSONObject idOfStudentToDelete_jsonObj = JSON.parseObject(request_json_str);
        //从JSONObject对象中读取键“id”的值（Java Object对象），
        Object id_obj = idOfStudentToDelete_jsonObj.get("id");
        int id_int = Integer.parseInt(id_obj.toString());

        //设置响应字符编码为UTF-8
        response.setContentType("application/json;charset=UTF-8");
        //创建JSON对象respMessage_jsonObj，以便往前端响应信息
        JSONObject respMessage_jsonObj = new JSONObject();
        try {
            //到数据库表中删除对应的Student
            StudentService.getInstance().delete(id_int);
            respMessage_jsonObj.put("message", "删除成功");
        } catch (SQLException e) {
            respMessage_jsonObj.put("message", "数据库操作异常");
            //打印异常栈，方便调试
            log.error(e.getMessage(),e);
        } catch (Exception e) {
            respMessage_jsonObj.put("message", "网络异常");
            //打印异常栈，方便调试
            log.error(e.getMessage(),e);
        }
        //响应respMessage_jsonObj到前端
        response.getWriter().println(respMessage_jsonObj);
    }

    //请使用以下JSON测试修改功能
    //{
    //    "id":"X",
    //    "name":"XXX",
    //    "no":"XX",
    //    "remarks":"",
    //    "studentClass":{
    //        "id":"X",
    //        "description":"XX",
    //        "no":"XX",
    //        "remarks":"",
    //        "department":{
    //            "id":"X",
    //            "description":"XX",
    //            "no":"XX",
    //            "remarks":"",
    //            "school":{
    //                "id":"X",
    //                "description":"XX",
    //                "no":"XX",
    //                "remarks":""
    //            }
    //        }
    //    }
    //}
    /**
     * PUT, http://localhost:8080/student.ctl, 修改学生
     * 修改一个学生对象：将来自前端请求的JSON对象
     * @author 1033299034@qq.com
     * @param request  请求对象
     * @param response 响应对象
     * @throws IOException
     */
    @Override
    protected void doPut(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //设置请求字符编码为UTF-8
        request.setCharacterEncoding("UTF-8");
        //根据request对象，获得代表参数的JSON字串
        String student_json = JSONUtil.getJSON(request);
        //将JSON字串解析为Student对象
        Student studentToAdd = JSON.parseObject(student_json, Student.class);

        //设置响应字符编码为UTF-8
        response.setContentType("application/json;charset=UTF-8");
        //创建JSON对象message，以便往前端响应信息
        JSONObject message = new JSONObject();
        //到数据库表修改Student对象对应的记录
        try {
            StudentService.getInstance().update(studentToAdd);
            message.put("message", "修改成功");
        } catch (SQLException e) {
            message.put("message", "数据库操作异常");
            //打印异常栈，方便调试
            log.error(e.getMessage(),e);
        } catch (Exception e) {
            message.put("message", "网络异常");
            //打印异常栈，方便调试
            log.error(e.getMessage(),e);
        }
        //响应message到前端
        response.getWriter().println(message);
    }

    //请使用以下JSON测试查询功能
    //查:根据id
    //{"id":"XX"}
    //    {
    //        "pagination":{
    //        "pageNo":"XX",
    //                "pageSize":"XX"
    //    },
    //        "conditionList":[
    //        {
    //            "value":"XX",
    //                "key":"XXXX",
    //                "operator":"LIKE"
    //        },
    //        {
    //            "value":"X",
    //                "key":"XXXX",
    //                "operator":"="
    //        }
    //    ]
    //    }
    /**
     * GET, http://localhost:8080/student.ctl, 查询学生
     * 查询学生对象：将来自前端请求的JSON对象
     * @author 1033299034@qq.com
     * @param request  请求对象
     * @param response 响应对象
     * @throws IOException
     */
    @Override
    protected void doGet(HttpServletRequest request,
                         HttpServletResponse response)
            throws ServletException, IOException {
        //创建JSON对象respMessage_jsonObj，以便往前端响应信息
        JSONObject respMessage_jsonObj = new JSONObject();

        //设置响应字符编码为UTF-8
        response.setContentType("application/json;charset=UTF-8");
        //将request body转换为JSON字串
        String req_jsonStr = JSONUtil.getJSON(request);
        //将request body解析为JSONObject对象
        JSONObject req_jsonObj = JSON.parseObject(req_jsonStr);
        //如果请求body为空
        if (req_jsonObj == null) {
            respMessage_jsonObj.put("message", "未收到请求信息！");
            response.getWriter().println(respMessage_jsonObj);
            return;
        }
        //从JSONObject对象中读取键“id”的值（Java Object对象），req_jsonObj可能是{"id":1}
        Object id_obj = req_jsonObj.get("id");
        try {
            //如果id_Obj != null, 说明请求数据有id键，是请求某个Student对象
            if (id_obj != null) {
                int id_int = Integer.parseInt(id_obj.toString());
                responseStudent(id_int, response);
            } else {//请求中包含条件和分页信息，需要响应多个Student对象
                //读取分页信息，形成分页对象
                //从JSONObject对象中读取 “pagination” 键对应的值(JSONObject对象)
                Pagination pagination = ControllerHelper.getPagination(req_jsonObj);

                List<Condition> conditionList = new ArrayList<Condition>();
                Object teacher_id_obj = req_jsonObj.get("teacher_id");
                if(teacher_id_obj != null){
                    String teacher_id_string = teacher_id_obj.toString();
                    Condition condition = new Condition("teacher_id","=",teacher_id_string);
                    conditionList.add(condition);
                }else {
                    //从请求JSONObject对象中读取键“conditionList”对应的值(描述查询条件的JSONArray对象)
                    conditionList = ControllerHelper.getConditions(req_jsonObj);
                }

                //响应多个Student信息，其中conditionList, pagination两个对象引用为空是可能的
                this.responseStudents(response, conditionList, pagination);
            }
        } catch (SQLException e) {
            respMessage_jsonObj.put("message", "数据库操作异常");
            e.printStackTrace();
            //响应respMessage_jsonObj到前端
            response.getWriter().println(respMessage_jsonObj);
            //打印异常栈，方便调试
            log.error(e.getMessage(),e);
        } catch (Exception e) {
            respMessage_jsonObj.put("message", "网络异常");
            //响应respMessage_jsonObj到前端
            response.getWriter().println(respMessage_jsonObj);
            //打印异常栈，方便调试
            log.error(e.getMessage(),e);
        }
    }

    //响应一个Student对象
    private void responseStudent(int id, HttpServletResponse response)
            throws ServletException, IOException, SQLException {
        //根据id查找Student
        Student student = StudentService.getInstance().find(id);
        String student_json = JSON.toJSONString(student);

        //响应Student_json到前端
        response.getWriter().println(student_json);
    }

    //按分页信息响应符合条件的Student对象和对象总数
    private void responseStudents(HttpServletResponse response,
                                  List<Condition> conditionList_json_str,
                                  Pagination pagination)
            throws ServletException, IOException, SQLException {
        //分页获得满足条件的所有Student
        Collection<Student> students = StudentService.getInstance()
                .findAll(conditionList_json_str,pagination);
        //第二个参数可以防止循环引用
        String students_jsonStr = JSON.toJSONString(students,
                SerializerFeature.DisableCircularReferenceDetect);
        //创建JSON对象resp_jsonObj，以便往前端响应综合信息
        JSONObject resp_jsonObj = new JSONObject();
        resp_jsonObj.put("totalNum", pagination.getTotalNum());
        resp_jsonObj.put("data", students_jsonStr);
        //响应resp_jsonObj到前端
        response.getWriter().println(resp_jsonObj);
    }
}
